<?php

declare(strict_types=1);

namespace Plugin\Attractions\HaiKang\Common;

use App\Exception\BusinessException;
use App\Http\Common\ResultCode;
use Common\Common;
use GuzzleHttp\Client;

class HKClient
{
    public function __construct()
    {
        $this->client = new Client([
            'base_uri' => self::BASE_URI,
            'timeout' => 10,
            'verify' => false, // 禁用SSL验证
        ]);
        $this->header = ['Authorization' => 'Bearer ' . $this->getAccessToken()];
    }
    private array $header;
    private Client $client;
    private const BASE_URI = "https://api2.hik-cloud.com";

    public function getAccessToken(bool $refresh = false): string
    {
        $data = Common::redis()->get('hkAccessToken');
        if (empty($data) || $refresh) {
            $clientID = Common::getConfig('hk_client_id');
            $clientSecret = Common::getConfig('hk_client_secret');
            $response = $this->client->post("/oauth/token", [
                'form_params' => [
                    'client_id' => $clientID,
                    'client_secret' => $clientSecret,
                    'grant_type' => 'client_credentials',
                ]
            ]);
            $data = $response->getBody()->getContents();
            $tokenData = json_decode($data, true);
            Common::redis()->SETEX('hkAccessToken', $tokenData['expires_in'], $data);
            return $tokenData['access_token'];
        }
        return json_decode($data, true)['access_token'];
    }

    public function request($method, $uri, $data = [], $header = []): array
    {
        $header = ['headers' => array_merge($this->header, $header)];

        // 发送请求
        try {
            $response = $this->client->request($method, $uri, array_merge($header, $data));
        } catch (\GuzzleHttp\Exception\ClientException $e) {
            // 捕获 401 异常并尝试刷新 token
            if ($e->getResponse()->getStatusCode() === 401) {
                $newToken = $this->getAccessToken(true);
                $header['headers']['Authorization'] = 'Bearer ' . $newToken;
                // 使用新 token 重试请求
                try {
                    $response = $this->client->request($method, $uri, array_merge($header, $data));
                } catch (\Exception) {
                    Common::log(__CLASS__, '海康请求失败 message:' . $e->getMessage() . ' line:' . $e->getLine() . ' data:' . json_encode($data), 'error');
                    throw new BusinessException(ResultCode::FAIL);
                }
            } else {
                Common::log(__CLASS__, '海康请求失败 message:' . $e->getMessage() . ' line:' . $e->getLine() . ' data:' . json_encode($data), 'error');
                throw new BusinessException(ResultCode::FAIL);
            }
        }

        // 获取响应体内容
        $response = json_decode($response->getBody()->getContents(), true);
        if (isset($response['code']) && ($response['code'] == 0 || $response['code'] == 200)) {
            return $response['data'];
        }
        Common::log(__CLASS__, '海康请求失败 line:' . __LINE__ . ' data:' . json_encode($data) . ' response:' . json_encode($response), 'error');
        throw new BusinessException(ResultCode::FAIL);
    }
}
